package com.yugao.fintech.antelope.auth.utils;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.util.StrUtil;
import com.yugao.fintech.antelope.base.model.constants.OAuth2Cons;
import com.yugao.fintech.antelope.base.model.enums.AuthErrorEnum;
import com.yugao.fintech.antelope.base.model.module.auth.OAuth2ParamKeys;
import com.yugao.fintech.framework.assistant.utils.StringUtils;
import com.yugao.fintech.framework.assistant.utils.exception.BizException;
import lombok.experimental.UtilityClass;
import org.springframework.http.HttpHeaders;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;

import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Map;

/**
 * OAuth2端点工具
 */
@UtilityClass
public class OAuth2Utils {
    public final String ACCESS_TOKEN_REQUEST_ERROR_URI = "https://datatracker.ietf.org/doc/html/rfc6749#section-5.2";

    public MultiValueMap<String, String> getParameters(HttpServletRequest request) {
        Map<String, String[]> parameterMap = request.getParameterMap();
        MultiValueMap<String, String> parameters = new LinkedMultiValueMap<>(parameterMap.size());
        parameterMap.forEach((key, values) -> {
            if (values.length > 0) {
                for (String value : values) {
                    parameters.add(key, value);
                }
            }
        });
        return parameters;
    }

    public static String[] obtainBasicAuthorization(HttpServletRequest request) {
        String clientId;
        String clientSecret;
        // 先从 Header 中获取
        String authorization = request.getHeader(HttpHeaders.AUTHORIZATION);
        authorization = StrUtil.subAfter(authorization, OAuth2Cons.TokenType.BASIC + " ", true);
        if (StringUtils.hasText(authorization)) {
            authorization = Base64.decodeStr(authorization);
            clientId = StrUtil.subBefore(authorization, ":", false);
            clientSecret = StrUtil.subAfter(authorization, ":", false);
            // 再从 Param 中获取
        } else {
            clientId = request.getParameter(OAuth2ParamKeys.CLIENT_ID);
            clientSecret = request.getParameter(OAuth2ParamKeys.CLIENT_SECRET);
        }

        // 如果两者非空，则返回
        if (StrUtil.isNotEmpty(clientId) && StrUtil.isNotEmpty(clientSecret)) {
            return new String[]{clientId, clientSecret};
        }
        return null;
    }

    public static List<String> buildScopes(String scope) {
        return StrUtil.split(scope, ' ');
    }

    public static String getHeaderToken(HttpServletRequest request, String tokenType) {
        String value = request.getHeader(HttpHeaders.AUTHORIZATION);
        if (StringUtils.isEmpty(value)) {
            throw new BizException(AuthErrorEnum.MISS_AUTH_HEADER);
        }
        return OAuth2Cons.TokenType.BASIC.equals(tokenType)
                ? Base64.decodeStr(value.replaceAll(tokenType + " ", ""))
                : value.replaceAll(tokenType + " ", "");
    }

}
